home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
COMMUNIC
/
UNIQWK21.ZIP
/
TALK.TXT
< prev
next >
Wrap
Text File
|
1993-07-11
|
14KB
|
425 lines
Talkline - How it works.
~~~~~~~~~~~~~~~~~~~~~~~~
Talkline is a sound of short duration, appended to the end of a message.
In this fist version, up to 5 seconds of sound can be added.
The purpose of this text file is to explain how the sound is coded
and appended to the message. This first version is called version "A" and
has the following characterization:
1-Sampling. - The sound bandwidth supports human voice only and so is sampled
at 5012.5Hz Hz, 8bits, with zero level at value 80h.
2-Compression -
A - The signal is converted to 4 bits, first subtracting DC value (80h) and
using a log (base 2) conversion of the absolute value:
in out
0 -> 0
0. .1 -> 1
2. .3 -> 2
4. .7 -> 3
8. .15 -> 4
16. .31 -> 5
32. .63 -> 6
64. .127 -> 7
Now the signal is 4 bits with zero level at 0 (-16 to 15).
B - The samples are packed 2 samples per byte, high nibble corresponding
to first sample and the low nibble to next one
EX:
t = 0 0000hhhh <-- 4 bit sample
1 0000LLLL
pack -> hhhhLLLL
C - Run lenght encoded, using FFh as flag character.
EX:
00 32 84 84 84 84 84 84 34 35 FF 54 54 FE FE FE FE FE FE
is converted to:
00 32 FF 05 84 34 35 FF 01 FF 54 54 FF 06 FE
3-Coding - The signal is coded using 7 bits, from 30h to AFh.
EX:
0 - AAAAaaaa - > 0 - 0AAAAaaa + 30h
1 - BBBBbbbb 1 - 0BBBBbbb + 30h
2 - CCCCcccc 2 - 0CCCCccc + 30h
3 - DDDDdddd 3 - 0DDDDddd + 30h
4 - EEEEeeee 4 - 0EEEEeee + 30h
5 - FFFFffff 5 - 0FFFFfff + 30h
6 - GGGGgggg 6 - 0GGGGggg + 30h
7 - 0abcdefg + 30h
4-Saving - The result is appended to the end of message at 64 bytes per line,
with a header:
"[TALK]" - 6 bytes - Identify a talkline
1Bh,"[8m" - 4 bytes - ANSI command to disable output, to avoid trash on
mail readers/terminal emulators without sound capabilities.
"A" - 1 byte - This version. Letters A to H are reserved.
"00000" - 5 bytes - The size of the sound in bytes, after coding and
without line feeds (E3h).
E3h - 1 byte - The character used as LF by the QWK file format.
.. follow first 64 bytes,E3h, and so on...
=========================================================================
As example, the routines, used to compress and expand the voice signal.
//-----------------------------------------------------------------------
UINT WaveCompress (LPSTR Pk, LPSTR Wav, UINT nS)
//
// Wav - intput signal
// Pk - output signal
// nS - number of data points
//
{
register UINT k, T;
char M;
UINT Ncomp, nS;
Log2(Wav, nS); ;4 bit convert
Ncomp = nS >> 1;
// pack data
_asm {
LES SI,Wav ;ES:SI -> Wav
MOV DI,SI
MOV CX,Ncomp
JCXZ DONE
L1: MOV AX,ES:[SI]
SHL AL,4 ;shift to HI nibble
AND AX,0FF0h ;mask
OR AL,AH ;merge
STOSB ;save
ADD SI,2
LOOP L1
DONE:
}
//
nS = 0;
Wav[Ncomp] = (char)(Wav[Ncomp-1]+1); //make last different
for(k=0; k<Ncomp; k++) //run lenght encode
{ T = 1;
M = Wav[k];
while (M == Wav[k+T]) //iqual next?
{ if(T == 253) break;
else T = T + 1; //yes, bump T
}
if(T > 2 || M == '\xFF')
{ Wav[nS++] = 0xFF; //mark
Wav[nS++] =(char)T; //total
k = k + T - 1; //next
}
Wav[nS++] = M; //save data
}
Ncomp = Pack(Pk, Wav, nS); //7 bits convert
return Ncomp;
}
//-----------------------------------------------------------------
LONG WaveExpand (LPSTR Wav, LPSTR Pk, UINT nS)
//
// Pk - input signal
// Wav - output signal
// nS - number of data points
//
{
register UINT T, k;
UINT Cnt;
LONG nExp, Pt;
//
nSamp = Unpack(Pk, Pk, nSamp); // 8 bits convert
nExp = 0; // run lenght decode
for(Pt=0; (UINT)Pt < nSamp; Pt++)
{ if(Pk[Pt] == (char) 0xFF )
{ Cnt = (BYTE) Pk[++Pt];
T = (char)Pk[++Pt];
for(k = 0; k < Cnt; k++) Wav[nExp++] = (char)T;
}
else
{ Wav[nExp++] = Pk[Pt]; }
}
Cnt =(UINT)nExp; //unpack
_asm {
LES DI, Wav
MOV BX,Cnt
OR BX,BX
JZ DONE
MOV SI,DI
ADD SI,BX ;end of data
ADD BX,BX ;end of unpacked data
L1: MOV AL,ES:[SI]
MOV AH,AL ;copy
SHR AL,4 ;do inverse operation
AND AX,0F0Fh ;mask
MOV ES:[DI+BX],AX ;save
DEC SI
SUB BX,2
JAE L1 ;for all data points
DONE:
}
//
nExp = nExp + nExp;
Exp2(Wave, nExp); ;8 bit convert
return nExp;
}
//=======================================================================
Assebly routines to convert to and from 7 bits.
;-------------------------------------------------------------------------
; UINT = Pack (LPSTR, LPSTR, UINT);
;
_Pack PROC FAR
PUSH BP
MOV BP,SP
PUSHF
CLD ;up
PUSH DS
PUSH SI
PUSH DI
XOR AX,AX ;zero return value
MOV CX,[BP+14] ;size (up to 64k)
JCXZ PACK9
LES DI,[BP+6];
LDS SI,[BP+10]; ;DS:SI -> string
XOR BX,BX ;byte count
ADD CX,SI ;offset end of input string
PUSH DI ;save it
;
PACK1: MOV DX,BX ;insert a 0E3h each 64 bytes
AND DX,3FH ;test
JNZ @F
MOV AL,0E3h ;LF (on QWK...)
STOSB ;insert
@@: CMP SI,CX ;end of processing?
JAE PACK2
LODSW ;-- 1 & 2
SHR AL,1 ;-> 7, bit 0 to CY
RCL DH,1 ;CY to bit 0 on DH
SHR AH,1 ;repeat to next byte
RCL DH,1
ADD AX,3030h ;translate to 30-A0h
STOSW ;ok, save it
LODSW
SHR AL,1 ;repeat for bytes 3 & 4
RCL DH,1
SHR AH,1
RCL DH,1
ADD AX,3030h
STOSW
LODSW
SHR AL,1 ;and 5 & 6
RCL DH,1
SHR AH,1
RCL DH,1
ADD AX,3030h
STOSW
LODSB
SHR AL,1 ;the last one...
RCL DH,1 ;
MOV AH,DH ;save DH (7 saved bits)
ADD AX,3030h ;
STOSW ;
ADD BX,8 ;total
JMP PACK1
PACK2: MOV AX,DI ;new position
POP DI ;initial position
SUB AX,DI ;return total processed bytes
PACK9: XOR DX,DX ;AX:DX
POP DI
POP SI
POP DS
POPF
MOV SP,BP
POP BP
RET
_Pack ENDP
;-------------------------------------------------------------
; UINT = Unpack (LPSTR, LPSTR, UINT);
;
_Unpack PROC FAR